﻿using CPPEI.WebApi.Packaging;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace CPPEI.WebApi.PackageTool
{
    /// <summary>
    /// PackagingWindow.xaml 的交互逻辑
    /// </summary>
    public partial class PackagingWindow : Window
    {
        private ModuleInfo _moduleInfo;

        public PackagingWindow()
        {
            InitializeComponent();

            _ctlBtnPackage.IsEnabled = false;
        }

        private void _ctlBtnBrowse_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Multiselect = false;
            dlg.Filter = "*.dll|*.dll";
            if(dlg.ShowDialog().Value)
            {
                _ctlEditPath.Text = dlg.FileName;

                LoadAssembly(dlg.FileName);
            }
        }

        private void LoadAssembly(string assemblyFile)
        {
            ModuleInfo module = AssemblyLoader.Load(assemblyFile);
            if(module.HasError)
            {
                _moduleInfo = null;

                _ctlBtnPackage.IsEnabled = false;
                MessageBox.Show(module.ErrorMessage, "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            else
            {
                _moduleInfo = module;

                _ctlPanelModule.DataContext = module;
                _ctlListRefs.ItemsSource = module.Refs;
                _ctlListActions.ItemsSource = module.Actions;
                _ctlBtnPackage.IsEnabled = true;
            }
        }

        private void _ctlBtnPackage_Click(object sender, RoutedEventArgs e)
        {
            SaveFileDialog dlg = new SaveFileDialog();
            dlg.Filter = "*.zip|*.zip";
            if(dlg.ShowDialog().Value)
            {
                string filePath = dlg.FileName;

                FileInfo fileInfo = new FileInfo(filePath);

                string tempDirectory = string.Format("{0}\\{1}\\", fileInfo.Directory.FullName, Guid.NewGuid().ToString("N"));
                // 生成一个临时目录,将文件都拷贝到临时文件夹里
                if(!Directory.Exists(tempDirectory))
                {
                    Directory.CreateDirectory(tempDirectory);
                }
                try
                {
                    CopyFileToTemp(_moduleInfo, tempDirectory);

                    // 压缩临时文件夹
                    if (CPPEI.WebApi.Packaging.PackageUtil.Compress(filePath, tempDirectory))
                    {
                        MessageBox.Show("Success:" + filePath);
                    }
                    else
                    {
                        MessageBox.Show("Failure");
                    }
                }
                catch(Exception ex)
                {

                }
                finally
                {
                    Directory.Delete(tempDirectory, true);
                }
            }
        }

        private void CopyFileToTemp(ModuleInfo module, string tempDirectory)
        {
            ModuleDef moduleDef = new ModuleDef();
            moduleDef.Assembly = module.Assembly;
            moduleDef.Name = module.Name;
            moduleDef.Type = module.Type;
            moduleDef.File = string.Format("{0}.dll", new AssemblyName(module.Assembly).Name);

            string moduleFilePath = GetFilePath(tempDirectory, module.Assembly);
            File.Copy(module.FilePath, moduleFilePath);

            foreach (RefInfo refInfo in module.Refs)
            {
                string refFilePath = GetFilePath(tempDirectory, refInfo.Assembly);
                File.Copy(refInfo.FilePath, refFilePath);

                RefDef refDef = new RefDef();
                refDef.Assembly = refInfo.Assembly;
                refDef.File = string.Format("{0}.dll", new AssemblyName(refInfo.Assembly).Name);
                moduleDef.Refs.Add(refDef);
            }

            foreach (ActionInfo actionInfo in module.Actions)
            {
                ActionDef actionDef = new ActionDef();
                actionDef.Scenario = actionInfo.Scenario;
                actionDef.Name = actionInfo.Name;
                actionDef.Type = actionInfo.Type;
                moduleDef.Actions.Add(actionDef);
            }

            ModuleDefDocument.Save(moduleDef, string.Format("{0}_module.xml", tempDirectory));

            Debug.WriteLine(">>write file to:" + tempDirectory);
        }

        private string GetFilePath(string directory, string assembly)
        {
            return string.Format("{0}{1}.dll", directory, new AssemblyName(assembly).Name);
        }
    }
}
